package com.uit.gis.controller;

import java.util.ArrayList;

import processing.data.JSONObject;

import com.uit.gis.config.DatabaseConfig;
import com.uit.gis.dao.ShapeDAO;
import com.uit.gis.pojo.Shape;
import com.uit.gis.ui.MainFrame;
import com.uit.gis.ui.MessageBoxDialog;
import com.uit.gis.ui.PanelDatabase;
import com.uit.gis.ui.PanelDrawing;
import com.uit.gis.util.ConnectionStatus;
import com.uit.gis.util.DatabaseDefine.TABLE_STATUS;
import com.uit.gis.util.JsonData;
import com.uit.gis.util.Language;
import com.uit.gis.util.OracleDataAccessHelper;
import com.uit.gis.util.Util.MessageBox;
import com.uit.gis.util.Util.MessageBoxIcon;

public class MainController {
	public final MainFrame mainFrame;
	OracleDataAccessHelper databaseHelper;
	private PanelDatabase panelDatabase;
	private PanelDrawing panelDrawing;
	public DatabaseConfig databaseConfig;

	// private PanelAbout panelAbout;

	public MainController() { 
		databaseHelper = new OracleDataAccessHelper();
		databaseConfig = new DatabaseConfig();
		mainFrame = new MainFrame(this);
	}

	// Database - begin
	public void openDatabase(String host, String port, String sId,
			String username, String password) {
		 ConnectionStatus status = databaseHelper.open(host, port, sId, username, password);
		 if(!status.isConnected)
		 { 
			 MessageBoxDialog.Show(status.errorString, Language.APP_NAME, MessageBox.OK, MessageBoxIcon.ERROR);
		 }
		 updateDatabaseGUI(status.isConnected);
	}

	public void closeDatabase() {
		if (databaseHelper != null && databaseHelper.isConnected()) {
			databaseHelper.close();
		}
	}

	public boolean databaseIsConnected() {
		if (databaseHelper != null && databaseHelper.isConnected()) {
			return true;
		}
		return false;
	}

	public boolean existingShapesTable() {
		if (databaseIsConnected()) {
			ShapeDAO shapeDAO = new ShapeDAO();
			return shapeDAO.tableExisting(databaseHelper);
		}
		return false;
	}

	public TABLE_STATUS createShapeTable() {
		ShapeDAO shapeDAO = new ShapeDAO();
		return shapeDAO.createTable(databaseHelper);
	}
	public ArrayList<Shape>  getShapeFromDatabase()
	{
		ShapeDAO shapeDAO = new ShapeDAO();
		return shapeDAO.getAllTable(databaseHelper); 
	}

	public void saveShapeToDatabase(Shape shape) {
		JsonData jsonData = shape.loadDataFromFile();
		StringBuffer bufferOrdinate = new StringBuffer();
		StringBuffer bufferElementInfo = new StringBuffer();

		
		switch (shape.getShapeName()) 
		{
		case LINE:
			{
				if (jsonData.array != null) {
					for (int i = 0; i < jsonData.array.size(); i++) {
						JSONObject object = jsonData.array.getJSONObject(i);
						bufferOrdinate.append(String.valueOf(object.getInt("x")) + ","
								+ String.valueOf(object.getInt("y")));
						if (i < jsonData.array.size() - 1) {
							bufferOrdinate.append(",");
						}
					}
				}
			// sdo_elem_info_array (1,2,1, 5,2,1)
			// (1,2,1): 1: index , 2- 1: point type [point one]
			// (5,2,1): 5: index, 2-1: point type [point two]
			// 2-1 : Line string whose vertices are connected by straight line
			// segments.
			int startIndex = 1;
			for (int i = 0; i < jsonData.array.size(); i++) {
				JSONObject object = jsonData.array.getJSONObject(i);
				bufferElementInfo.append(String.valueOf(startIndex) + ",2,1"); 
				if (i < jsonData.array.size() - 1) {
					bufferElementInfo.append(",");
				}
				startIndex += object.size();
			  }
			} 
			break;
		case CUSTOM_SHAPE:
		{
			int startIndex = 1;
			for (int i = 0; i < jsonData.array.size(); i++) {
				JSONObject object = jsonData.array.getJSONObject(i);
				bufferOrdinate.append(object.getInt("x1")+","+object.getInt("y1")+",");
				bufferOrdinate.append(object.getInt("x2")+","+object.getInt("y2")); 
				bufferElementInfo.append(String.valueOf(startIndex) + ",2,1,");   
				startIndex += 2;
				bufferElementInfo.append(String.valueOf(startIndex) + ",2,1");  
				if(i < jsonData.array.size() -1)
				{
					bufferOrdinate.append(",");
					bufferElementInfo.append(",");
				}
				startIndex += 2;
			  }
		}
		break;
		case POINTS:
		{
			if (jsonData.array != null) {
				for (int i = 0; i < jsonData.array.size(); i++) {
					JSONObject object = jsonData.array.getJSONObject(i);
					bufferOrdinate.append(String.valueOf(object.getInt("x")) + ","
							+ String.valueOf(object.getInt("y")));
					if (i < jsonData.array.size() - 1) {
						bufferOrdinate.append(",");
					}
				}
			}
			// sdo_elem_info_array (1,1,1, 2,1,1)
			// 1 & 2 in first: index
			//1-1 : point
			int startIndex = 1;
			for (int i = 0; i < jsonData.array.size(); i++) { 
				bufferElementInfo.append(String.valueOf(startIndex) + ",1,1"); 
				if (i < jsonData.array.size() - 1) {
					bufferElementInfo.append(",");
				}
				startIndex += 2;
			  }
		}
       break;
		case RECTANGLE:
		{
			JSONObject rectObj = jsonData.object;
			int firstX = rectObj.getInt("x");
			int firstY = rectObj.getInt("y");
			int w = rectObj.getInt("w");
			int h = rectObj.getInt("h");
			int lastX = firstX + w;
			int lastY = firstY + h;
			//(x1,y1)//////////////////(x2,y1)
			//								 //
			//	 lower left and upper right  //
			//   y increase from top to down //
			//								 //
			//(x1,y2)//////////////////(x2,y2)
			
			int x1 = lastX <= firstX ? lastX :firstX;
			int x2 = lastX >= firstX ? lastX :firstX;
			int y1 = lastY <= firstY ? lastY :firstY;
			int y2 = lastY >= firstY? lastY :firstY;
			bufferElementInfo.append("1,1003,3");// rectangle : 1003 = exterior
			bufferOrdinate.append(String.valueOf(x1+","+y2+","+x2+","+y1));
		}
		break;
 
		case ELLIPSE:
		{
			
		}
		break;
		case ARC:
		{
			bufferElementInfo.append("1,2,2"); 
			if (jsonData.array != null) {
				for (int i = 0; i < jsonData.array.size(); i++) {
					JSONObject object = jsonData.array.getJSONObject(i);
					bufferOrdinate.append(String.valueOf(object.getInt("x")) + ","
							+ String.valueOf(object.getInt("y")));
					if (i < jsonData.array.size() - 1) {
						bufferOrdinate.append(",");
					}
				}
			}
		}
		break;
		//polygon
		case QUAD:
		case TRIANCLE:
		{
			if (jsonData.array != null) {
				for (int i = 0; i < jsonData.array.size(); i++) {
					JSONObject object = jsonData.array.getJSONObject(i);
					bufferOrdinate.append(String.valueOf(object.getInt("x")) + ","
							+ String.valueOf(object.getInt("y")));
					if (i < jsonData.array.size() - 1) {
						bufferOrdinate.append(",");
					}
				}
			}
			bufferElementInfo.append("1,1003,1"); 
			 
		}
		break;
		case CIRCLE:
		{
			bufferElementInfo.append("1,1003,4");
			bufferOrdinate.append(jsonData.object.getInt("x1")+","+jsonData.object.getInt("y1")+",");
			bufferOrdinate.append(jsonData.object.getInt("x2")+","+jsonData.object.getInt("y2")+",");
			bufferOrdinate.append(jsonData.object.getInt("x3")+","+jsonData.object.getInt("y3"));
		}
		break;
		case BOX:
		{
			bufferElementInfo.append("1,1003,3,"+jsonData.object.getInt("d")+","+
		    jsonData.object.getInt("w")+","+jsonData.object.getInt("h"));
			bufferOrdinate.append(jsonData.object.getInt("x")+","+jsonData.object.getInt("y"));
			 
		}
		break;
		default:
			break;
		}
		ShapeDAO shapeDAO = new ShapeDAO();
		boolean result = shapeDAO.saveShape(databaseHelper, shape,
				bufferElementInfo, bufferOrdinate);
		panelDrawing.saveSaveInfor(result); // invoke to GUI
		panelDrawing.updateTable(true);
	}

	// Database - end
	public void updateDatabaseGUI(boolean connected) {
		this.panelDrawing.updateDatabaseGUI(connected);
		this.panelDatabase.updateConnectionGUI(connected);
		this.panelDrawing.updateTable(connected);
	}

	public PanelDatabase getPanelDatabase() {
		return panelDatabase;
	}

	public void setPanelDatabase(PanelDatabase panelDatabase) {
		this.panelDatabase = panelDatabase;
	}

	public PanelDrawing getPanelDrawing() {
		return panelDrawing;
	}

	public void setPanelDrawing(PanelDrawing panelDrawing) {
		this.panelDrawing = panelDrawing;
	}

}
